package org.ChrisRiffle.Acme.AcmeTraverser;

import java.io.File;
import java.util.logging.Logger;

import org.ChrisRiffle.Acme.AcmeTraverser.ActionPerformers.FilePathModDatePerformer;




/**
 * Main entry point launcher of the application. Demonstrates the Traverser
 * framework to traverse a file system and perform actions on {@link ActionPerformer} 
 * objects
 * 
 * @author RIF
 * 
 */
public class TraverserLauncher {

	/**
	 * Application main entry point. Two arguments below are supported, of which the
	 * order is significant.
	 * 
	 * @param args
	 *            The 1st argument is the file system absolute path to a file or
	 *            directory for which actions will be recursively performed upon
	 *            by the {@link TraverserControler}
	 * 
	 *            The 2nd argument is the class path reference(just the package
	 *            name with dot notation and the class name after the last dot)
	 *            to represent the {@link ActionPerformer} that will be used to
	 *            act on all the files processed by the
	 *            {@link TraverserControler}
	 * 
	 * 
	 *            Example: org.ChrisRiffle.Acme.JFileTraverser.actionPerformers.
	 *            FilePathModDatePerformer
	 * 
	 *            This example is also the default {@link ActionPerformer} that
	 *            will be used in case the 2nd argument is not passed into the
	 *            main method, or in the case that the 2nd argument is invalid
	 *            or unusable
	 * 
	 */
	public static void main(String... args) {

		if(args.length == 0){
			
			Logger.getAnonymousLogger().severe(
					"At least 1 argument (file/dir path) must be specified, EXITING");
			
			System.exit(0);
		}
		
		TraverserLauncher tL = new TraverserLauncher();
				
		String filePathToTraverse = args[0];
		
				
		Logger.getAnonymousLogger().info("Using file path: " + filePathToTraverse);

		
		String classPathOfObjectToInit = null;
		
		if(args.length > 1){			 
			
			//attempt registering each action performer that the user specified
			for(int i=1; i<args.length; i++){
								
				// if this doesn't get set(user didn't specify), then the default action performer 
				// will be used
				classPathOfObjectToInit = args[i];
				
				tL.registerActionPerformer(classPathOfObjectToInit);		
			}
			

		}
		
		if(TraverserControler.INSTANCE.getActionPerformerList().size() == 0){

			/* At this point, the performer(s) weren't able to be created with
			 * reflection based on the package name specified by the user, (or
			 * maybe the user didn't specify one at all) so we will fall back on
			 * creating/using our default action performer object
			 */
			Logger.getAnonymousLogger().warning(
			"No performer from the console, using default internal ActionPerformer");
	
			ActionPerformer defaultPerformer = new FilePathModDatePerformer();
			TraverserControler.INSTANCE.addActionPerformer(defaultPerformer);
			
		}
			
		// now here, either the default performer will process(if the user didn't 
		// specify any), or all of the ones specified by the user will process
		TraverserControler.INSTANCE.traverse(new File(filePathToTraverse));
		
		TraverserControler.INSTANCE.shutDownPerformers();
	}

	
	/**
	 * Launches the application
	 * 
	 * @param pFilePathToTraverse
	 *            The file path to traverse
	 * 
	 * @param pActionPerformer
	 *            To perform the action on files processed by the Traverser
	 */
	public void registerActionPerformer(String pActionPerformerClassPath) {


		ActionPerformer actionPerformer = null;

		try {
			
			if(pActionPerformerClassPath != null){
			
				/*
				 * Instantiate an instance of the class by using java 
				 * reflection
				 */
				Class reflectedClassToInit = Class.forName(pActionPerformerClassPath);

				actionPerformer = (ActionPerformer) reflectedClassToInit.newInstance();	
				
				TraverserControler.INSTANCE.addActionPerformer(actionPerformer);
				
				Logger.getAnonymousLogger().info(
						"Successfully parsed/added ActionPerformer: " + pActionPerformerClassPath);
				
			}
			
		} catch (ClassNotFoundException e) {

			e.printStackTrace();

		} catch (InstantiationException e) {

			e.printStackTrace();
		
		} catch (IllegalAccessException e) {

			e.printStackTrace();
		}



		
		
	
	}

}
